package com.niiwoo.civet.account.service.local.trade;

import com.niiwoo.civet.account.dto.bill.AddBillDetailDTO;
import com.niiwoo.civet.account.enums.BillRemark3Enum;
import com.niiwoo.civet.account.enums.BillSecondSubjectEnum;
import com.niiwoo.civet.account.enums.OrderTypeEnum;
import com.niiwoo.civet.base.dto.BaseFeeDetailDTO;
import com.niiwoo.civet.base.enums.FeeTypeEnum;
import com.niiwoo.civet.base.enums.OrderRefundTypeEnum;
import com.niiwoo.tripod.lanmao.enums.BusinessTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 账单明细生成器
 * Created by wangjichao on 2018/4/24.
 */
@Service
@Slf4j
public class BillDetailListGenerator {


    /**
     * 还款/垫付 账单明细生成
     * @param orderTypeEnum
     * @param orderRefundTypeEnum
     * @param baseFeeDetailDTOList
     * @return
     */
    public List<AddBillDetailDTO> generateRepaymentBillDetailList(
            OrderTypeEnum orderTypeEnum,
            OrderRefundTypeEnum orderRefundTypeEnum,
            List<BaseFeeDetailDTO> baseFeeDetailDTOList){

        List<AddBillDetailDTO> addBillDetailDTOList = new ArrayList<>();
        //还款
        if(orderTypeEnum == OrderTypeEnum.REPAYMENT){
            addBillDetailDTOList = this.generateRefundBillDetailList(orderRefundTypeEnum,baseFeeDetailDTOList);
        }
        //垫付/机构代偿
        else if(orderTypeEnum == OrderTypeEnum.GUARANTEE){
            addBillDetailDTOList =  this.generateAdvanceBillDetailList(baseFeeDetailDTOList);
        }
        return addBillDetailDTOList;
    }


    /**
     * 回款记账类目
     * @param businessTypeEnum
     * @param baseFeeDetailDTOList
     * @return
     */
    public List<AddBillDetailDTO> generateReceiveRepaymentBillDetailList(
            BusinessTypeEnum businessTypeEnum,
            List<BaseFeeDetailDTO> baseFeeDetailDTOList){
        List<AddBillDetailDTO> addBillDetailDTOList = new ArrayList<>();
        //还款回款：借款人->投资人
        if(businessTypeEnum == BusinessTypeEnum.REPAYMENT){
            addBillDetailDTOList = this.generateReceiveRepaymentBillDetailListBorrower2Investor(baseFeeDetailDTOList);
        }
        //垫付回款：担保公司->投资人
        else if(businessTypeEnum == BusinessTypeEnum.COMPENSATORY){
            addBillDetailDTOList = this.generateReceiveRepaymentBillDetailListGuarantee2Investor(baseFeeDetailDTOList);
        }
        //还代偿款：借款人->担保公司
        else if(businessTypeEnum == BusinessTypeEnum.COMPENSATORY_REPAYMENT){
            addBillDetailDTOList = this.generateReceiveRepaymentBillDetailListBorrower2Guarantee(baseFeeDetailDTOList);
        }
        //平台管理费和担保服务费统一处理
        AddBillDetailDTO addBillDetailDTO = null;
        for(BaseFeeDetailDTO baseFeeDetailDTO : baseFeeDetailDTOList){
            if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.MANAGEMENT_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.PLATFORM_SERVICE_FEE_IN_MANAGE_SPEED_BORROWING);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.GUARANTEE_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_IN_REPAYMENT);
                addBillDetailDTOList.add(addBillDetailDTO);
            }else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CONSULTING_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.CONSULTING_FEE_IN);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
        }
        return addBillDetailDTOList;
    }

    /**
     * 还款回款：借款人->投资人
     * @param baseFeeDetailDTOList
     * @return
     */
    public List<AddBillDetailDTO> generateReceiveRepaymentBillDetailListBorrower2Investor(List<BaseFeeDetailDTO> baseFeeDetailDTOList){
        List<AddBillDetailDTO> addBillDetailDTOList = new ArrayList<AddBillDetailDTO>();
        AddBillDetailDTO addBillDetailDTO = null;
        for(BaseFeeDetailDTO baseFeeDetailDTO : baseFeeDetailDTOList){
            if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CAPITAL){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(BillRemark3Enum.INVESTMENT_PAYBACK_CORPUS_BORROW.getDesc());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_CORPUS);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.INTEREST){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(BillRemark3Enum.INVESTMENT_PAYBACK_INTEREST_BORROW.getDesc());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_INTEREST);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.PENALTY){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(BillRemark3Enum.INVESTMENT_PAYBACK_OVERDUE_FEE_BORROW.getDesc());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_PENALTY);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
        }
        return addBillDetailDTOList;
    }

    /**
     * 垫付回款：担保公司->投资人
     * @param baseFeeDetailDTOList
     * @return
     */
    public List<AddBillDetailDTO> generateReceiveRepaymentBillDetailListGuarantee2Investor(List<BaseFeeDetailDTO> baseFeeDetailDTOList){
        List<AddBillDetailDTO> addBillDetailDTOList = new ArrayList<AddBillDetailDTO>();
        AddBillDetailDTO addBillDetailDTO = null;
        for(BaseFeeDetailDTO baseFeeDetailDTO : baseFeeDetailDTOList){
            if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CAPITAL){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(BillRemark3Enum.INVESTMENT_PAYBACK_CORPUS_GUARANTEE_COMPANY.getDesc());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_CORPUS);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.INTEREST){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(BillRemark3Enum.INVESTMENT_PAYBACK_INTEREST_GUARANTEE_COMPANY.getDesc());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_INTEREST);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.PENALTY){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(BillRemark3Enum.INVESTMENT_PAYBACK_PENALTY_GUARANTEE_COMPANY.getDesc());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_PENALTY);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
        }
        return addBillDetailDTOList;
    }

    /**
     * 还代偿款回款：借款人->担保公司
     * @param baseFeeDetailDTOList
     * @return
     */
    public List<AddBillDetailDTO> generateReceiveRepaymentBillDetailListBorrower2Guarantee(List<BaseFeeDetailDTO> baseFeeDetailDTOList){
        List<AddBillDetailDTO> addBillDetailDTOList = new ArrayList<AddBillDetailDTO>();
        AddBillDetailDTO addBillDetailDTO = null;
        for(BaseFeeDetailDTO baseFeeDetailDTO : baseFeeDetailDTOList){
            if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CAPITAL){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_IN_REPAYMENT_PRINCIPAL);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.INTEREST){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_IN_REPAYMENT_INTEREST);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.PENALTY){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_IN_REPAYMENT_PENALTY);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
        }
        return addBillDetailDTOList;
    }


    /**
     * 获取借款人-还款中账单流水明细
     * @param orderRefundTypeEnum
     * @param baseFeeDetailDTOList
     * @return
     */
    private List<AddBillDetailDTO> generateRefundBillDetailList(OrderRefundTypeEnum orderRefundTypeEnum,
                                                                   List<BaseFeeDetailDTO> baseFeeDetailDTOList){
        //获取备注
        BillRemark3Enum billRemark3Enum = this.getRepaymentBillRemark2(orderRefundTypeEnum);
        //转换明细
        List<AddBillDetailDTO> addBillDetailDTOList = new ArrayList<AddBillDetailDTO>();
        AddBillDetailDTO addBillDetailDTO = null;
        for(BaseFeeDetailDTO baseFeeDetailDTO : baseFeeDetailDTOList){
            if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CAPITAL){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(billRemark3Enum.getDesc());//备注
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_REPAYMENT_CORPUS);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.INTEREST){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(billRemark3Enum.getDesc());//备注
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_REPAYMENT_INTEREST);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.PENALTY){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(billRemark3Enum.getDesc());//备注
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_REPAYMENT_PENALTY);
                addBillDetailDTOList.add(addBillDetailDTO);
            }else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.MANAGEMENT_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(billRemark3Enum.getDesc());//备注
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_REPAYMENT_MANAGER_FEE);
                addBillDetailDTOList.add(addBillDetailDTO);
            }else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.GUARANTEE_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(billRemark3Enum.getDesc());//备注
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_REPAYMENT_GUARANTEE_FEE);
                addBillDetailDTOList.add(addBillDetailDTO);
            }else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CONSULTING_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setRemark2(billRemark3Enum.getDesc());//备注
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.USER_REPAYMENT_CONSULTING_FEE);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
        }
        return addBillDetailDTOList;
    }

    /**
     * 垫付
     * @param baseFeeDetailDTOList
     * @return
     */
    private List<AddBillDetailDTO> generateAdvanceBillDetailList(List<BaseFeeDetailDTO> baseFeeDetailDTOList){
        //转换明细
        List<AddBillDetailDTO> addBillDetailDTOList = new ArrayList<AddBillDetailDTO>();
        AddBillDetailDTO addBillDetailDTO = null;
        for(BaseFeeDetailDTO baseFeeDetailDTO : baseFeeDetailDTOList){
            if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CAPITAL){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_OUT_PRINCIPAL_SPEED_BORROW);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.INTEREST){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_OUT_INTEREST);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
            else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.PENALTY){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_OUT_PENALTY);
                addBillDetailDTOList.add(addBillDetailDTO);
            }else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.MANAGEMENT_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_OUT_MANAGE_FEE);
                addBillDetailDTOList.add(addBillDetailDTO);
            }else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.GUARANTEE_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_OUT_GUARANTEE_FEE);
                addBillDetailDTOList.add(addBillDetailDTO);
            }else if(baseFeeDetailDTO.getFeeTypeEnum() == FeeTypeEnum.CONSULTING_FEE){
                addBillDetailDTO = new AddBillDetailDTO();
                addBillDetailDTO.setAmount(baseFeeDetailDTO.getAmount());
                addBillDetailDTO.setBillSecondSubjectEnum(BillSecondSubjectEnum.GUARANTEE_AGENCY_ADVANCE_GUARANTEE_OUT_CONSULTING_FEE);
                addBillDetailDTOList.add(addBillDetailDTO);
            }
        }
        return addBillDetailDTOList;
    }


    /**
     * 获取还款/垫付账单明细表备注2字段
     * @param orderRefundTypeEnum
     * @return
     */
    private BillRemark3Enum getRepaymentBillRemark2(OrderRefundTypeEnum orderRefundTypeEnum) {
        //正常还款
        if(orderRefundTypeEnum == OrderRefundTypeEnum.NORMAL_REFUND){
            return BillRemark3Enum.REPAYMENT_NORMAL;
        }
        //提前结清
        else if(orderRefundTypeEnum == OrderRefundTypeEnum.OVERDEPT_REFUND){
            return BillRemark3Enum.REPAYMENT_ADVANCE;
        }
        //坏账还款
        else if(orderRefundTypeEnum == OrderRefundTypeEnum.BADLOAN_REFUND){
            return BillRemark3Enum.REPAYMENT_OVERDUE_BAD;
        }
        //逾期还款
        else if(orderRefundTypeEnum == OrderRefundTypeEnum.OVERDUE_REFUND){
            return BillRemark3Enum.REPAYMENT_OVERDUE;
        }
        return BillRemark3Enum.REPAYMENT_NORMAL;
    }
}
